﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using ProtoBuf;
using ZyGames.Framework.Common;
using ZyGames.Framework.Game.Cache;
using ZyGames.Framework.Net;
using ZyGames.Framework.Cache.Generic;

namespace ZyGames.DZPocker.Model
{
	/// <summary>
	/// 桌子对象
	/// </summary>
	[Serializable, ProtoContract]
	public class TableData : BaseDisposable
	{
		/// <summary>
		/// 不包括大小王52张牌
		/// </summary>
		private const int PackMaxNum = 52;
		/// <summary>
		/// 桌子上的底牌数量
		/// </summary>
		public const int CardBackNum = 5;

		/// <summary>
		/// 操作超时时间(5秒)
		/// </summary>
		public int OperationSecTimeout;

		/// <summary>
		/// 没有筹码之后几(两)分钟之内不申请筹码的话则强制站起
		/// </summary>
		public int ForceLeaveFromTableTimeout;

		/// <summary>
		/// 服务器操作延时时间(500毫秒)
		/// </summary>
		public int OperationSecTimeoutOffset;

		/// <summary>
		/// 延时药水的延时时间(20秒  这里毫秒单位)
		/// </summary>
		public int MedecineTimeDelay;

		/// <summary>
		/// 筹码移动到底池时间(3s)
		/// </summary>
		public int ChipMoveTimeToTablePool;

		/// <summary>
		/// 一局结束到另外一局开始间隔时间(2s)
		/// </summary>
		public int CheckStartTime;

		/// <summary>
		/// 保险操作的响应时间
		/// </summary>
		public int InsuranceOperationTime;

		/// <summary>
		/// 玩家下注筹码移动时间
		/// </summary>
		public int ChipMoveTime;

		/// <summary>
		/// 房间编号
		/// </summary>
		private int _roomId;
		/// <summary>
		/// 桌子标号
		/// </summary>
		private int _tableId;
		/// <summary>
		/// 桌子邀请码
		/// </summary>
		private int _inviteNum;

		/// <summary>
		/// 盲注等级
		/// </summary>
		public BindLevelCostsInfo BindLevelCost;

		/// <summary>
		/// 时间等级
		/// </summary>
		public TimeLevelCostsInfo TimeLevelCost;

		/// <summary>
		/// 当前房间的默认筹码数量
		/// </summary>
		public int Chip { get; set; }

		#region property

		/// <summary>
		/// 房间ID
		/// </summary>
		[ProtoMember(1)]
		public int RoomId
		{
			get { return _roomId; }
			set { _roomId = value; }
		}
		/// <summary>
		/// 桌子编号
		/// </summary>
		[ProtoMember(2)]
		public int TableId
		{
			get { return _tableId; }
			set { _tableId = value; }
		}

		/// <summary>
		/// 桌子邀请码
		/// </summary>
		[ProtoMember(3)]
		public int InviteNum
		{
			get { return this._inviteNum; }
			set { this._inviteNum = value; }
		}

		/// <summary>
		/// 桌位数据
		/// </summary>
		[ProtoMember(4)]
		public PositionData[] Positions
		{
			get { return _positions; }
			set { _positions = value; }
		}

		/// <summary>
		/// 可以容纳玩的总人数
		/// </summary>
		[ProtoMember(5)]
		public int PlayerNum
		{
			get { return _playerNum; }
			set { _playerNum = value; }
		}

		/// <summary>
		/// 一副牌数据
		/// </summary>
		public List<int> CardData
		{
			get { return _cardList; }
			set { _cardList = value; }
		}

		/// <summary>
		/// 一副牌数据的备份,不包括已经发掉的牌
		/// </summary>
		public List<int> BackUpCardData;

		/// <summary>
		/// 底牌数据
		/// </summary>
		public List<int> BackCardData
		{
			get { return _backCardData; }
			set { _backCardData = value; }
		}

		/// <summary>
		/// 五张底牌的临时存在的容器
		/// </summary>
		[ProtoMember(6)]
		public List<int> TempBackCardData { get; set; }

		/// <summary>
		/// 保险对象
		/// </summary>
		//public InsuranceModel InsuranceModelData;

		/// <summary>
		/// 当前在桌子中的玩家
		/// </summary>
		[ProtoMember(7)]
		public List<GameUser> PlayersData
		{
			get { return _playerData; }
			set { _playerData = value; }
		}

		/// <summary>
		/// 是否明牌
		/// </summary>
		public bool IsShow { get; set; }

		/// <summary>
		/// 当前庄家位置
		/// </summary>
		[ProtoMember(8)]
		public int BankerPos { get; set; }

		/// <summary>
		/// 当前庄家
		/// </summary>
		[ProtoMember(9)]
		public int BankerId { get; set; }

		/// <summary>
		/// 当前底池的筹码数
		/// </summary>
		[ProtoMember(10)]
		public int AnteNum
		{
			get { return _currAnteNum; }
			set { _currAnteNum = value; }
		}
		/// <summary>
		/// 出牌结束
		/// </summary>
		//public bool IsClosed { get; set; }

		/// <summary>
		/// 是否逃跑
		/// </summary>
		public bool IsFlee { get; set; }

		/// <summary>
		/// 出牌玩家
		/// </summary>
		public int OutCardPos { get; set; }

		public int OutCardUserId { get; set; }

		/// <summary>
		/// 当前庄家在玩家中的索引用这个能得到某个玩家然后获得他属性中座位号
		/// </summary>
		private int bankerIndex = -1;

		/// <summary>
		/// 当前位置Index（0-8）
		/// </summary>
		private int currentPosIndex = -1;

		/// <summary>
		/// 当前庄家的位置
		/// </summary>
		private PositionData currentBankerPos = null;

		/// <summary>
		/// 当前正在操作保险的位置
		/// </summary>
		public PositionData CurrentInsurancePos = null;

		/// <summary>
		/// 当前这一轮最大的下注玩家座位Id
		/// </summary>
		private int currentRoundMaxChipPosId = -1;

		/// <summary>
		/// 当前回合最大的下注数量是
		/// </summary>
		private int currentRoundMaxChip = 0;

		/// <summary>
		/// 累计下注 9个玩家的筹码
		/// </summary>
		public int[] TotalScore = new int[9];

		/// <summary>
		/// 桌面下注
		/// </summary>
		public int[] TableScore = new int[9];

		/// <summary>
		/// 最大下注
		/// </summary>
		public int[] MaxScore = new int[9];

		/// <summary>
		/// 下注记录
		/// </summary>
		private Dictionary<int, List<KeyValuePair<int, int>>> betRecord;
		/// <summary>
		/// 申请筹码记录，第一个参数UserId
		/// </summary>
		public Dictionary<int, int> ApplyChipRecore;

		#endregion

		private bool _canNotOnLooking;
		/// <summary>
		/// 是否允许旁观
		/// </summary>
		[ProtoMember(20)]
		public bool CanNotOnLooking
		{
			get { return _canNotOnLooking; }
			set { _canNotOnLooking = value; }
		}

		private bool insurance;
		/// <summary>
		/// 是否开通保险功能
		/// </summary>
		[ProtoMember(21)]
		public bool Insurance
		{
			get { return insurance; }
			set { insurance = value; }
		}

		private int vip;
		/// <summary>
		/// VIP功能(0:没有开通VIP，1.每手收费, 2.每局收费)
		/// </summary>
		[ProtoMember(22)]
		public int Vip
		{
			get { return vip; }
			set { vip = value; }
		}

		/// <summary>
		/// 是否开通vip功能
		/// </summary>
		public bool IsVIP
		{
			get { return vip != 0; }
		}

		/// <summary>
		/// 是否强制抓头
		/// </summary>
		[ProtoMember(24)]
		public bool IsGripper { get; set; }

		/// <summary>
		/// 保险人ID
		/// </summary>
		private int _insureId;
		/// <summary>
		/// 保险人ID
		/// </summary>
		[ProtoMember(25)]
		public int InsureId
		{
			get { return _insureId; }
			set { _insureId = value; }
		}

		/// <summary>
		/// 是否从保险人页面切换到游戏页面状态
		/// </summary>
		[ProtoMember(30)]
		public bool IsChangePlayState { get; set; }

		//TODO:记录每个玩家的筹码消费,并且要记录到Proto中

		//TODO:记录玩家的压注记录

		private PositionData[] _positions;
		/// <summary>
		/// 房间成员数量(默认是9个人，从数据库配置读取的)
		/// </summary>
		private int _playerNum = 9;
		/// <summary>
		/// 当前底池的金币数
		/// </summary>
		private int _currAnteNum = 0;
		private List<int> _cardList;
		/// <summary>
		/// 桌子上的牌
		/// </summary>
		private List<int> _backCardData;
		private List<GameUser> _playerData;
		private List<CardData> _outCardList;
		/// <summary>
		/// 当前正在玩的座位
		/// </summary>
		public List<PositionData> CurrentPlayingPositionData;
		//房间游戏的定时器
		private Timer _timer;
		/// <summary>
		/// 房间开局的时间
		/// </summary>
		private System.Timers.Timer tableTimer;
		private int totalSecond = 0;
		private int _timerPeriod = 0;
		/// <summary>
		/// 操作计数
		/// </summary>
		private int _timeNumber = 0;
		/// <summary>
		/// 下注回合,顶多下四个回合的注
		/// </summary>
		public int Round = 0;

		/// <summary>
		/// 是否在发了手牌的时候大家就AllIn了，并且在勾选了保险功能的房间, 这要求三张牌分开发，分开计算保险
		/// </summary>
		public bool FirstRoundAllInInInsuranceTable = false;
		/// <summary>
		/// 第一回合开始发三张牌，触发保险的时候分开发的次数
		/// </summary>
		public int FirstRoundAllInPopCardTimes = 0;

		private TableState _tableState = TableState.None;

		public bool TimeIsOver = false;

		/// <summary>
		/// 是否已经开局发牌了
		/// </summary>
		public bool IsHavaSendCards = false;

		/// <summary>
		/// 定时器的启动时间
		/// </summary>
		private DateTime beginTime;

		/// <summary>
		/// 上一个正常下注的位置
		/// </summary>
		public int FormalNormalOperatePosID = 0;

		/// <summary>
		/// 是否是AllIn看牌状态
		/// </summary>
		public bool AllInState = false;

		/// <summary>
		/// 上一次下注的位置
		/// </summary>
		public int FormalOperatePosId = 0;

		/// <summary>
		/// 游戏房间的状态(开始游戏之后就切换成play状态)
		/// </summary>
		[ProtoMember(31)]
		public TableState State
		{
			get { return _tableState; }
			set { _tableState = value; }
		}

		[ProtoMember(32)]
		public int BindLevel { get; set; }

		[ProtoMember(33)]
		public int TimeLevel { get; set; }

		[ProtoMember(34)]
		public string TableName { get; set; }

		/// <summary>
		/// 当期是第几手牌局
		/// </summary>
		[ProtoMember(35)]
		public int HandVersionID { get; set; }

		/// <summary>
		/// 保险人
		/// </summary>
		public Insurer TableInsurer = null;

		/// <summary>
		/// 九个位置的保险赔付
		/// </summary>
		//public int[] InsureChip;

		/// <summary>
		/// 上一回合谁操作的保险
		/// </summary>
		public int InsureOperatePosId;

		/// <summary>
		/// 房主点击开始游戏按钮状态
		/// </summary>
		public bool TableReadyStart = false;

		/// <summary>
		/// 房主
		/// </summary>
		public GameUser TableMaster = null;

		/// <summary>
		/// 实时战绩字典
		/// </summary>
		private Dictionary<int, RealTimeRecord> realTimeRecordList = null;

		/// <summary>
		/// AllIn状态下的筹码底池
		/// </summary>
		private Dictionary<int, int> tempTableChipPool = null;

		/// <summary>
		/// 玩家购买的保险记录,第一个是位置id， 后面是购买保险总额和实际支付的保险筹码
		/// </summary>
		private Dictionary<int, List<KeyValuePair<int, int>>> tempInsuranceRecord = null;

		/// <summary>
		/// 总共的牌桌时间
		/// </summary>
		public int TotalTime = 0;

		/// <summary>
		/// 买保险index
		/// </summary>
		//public int winnerListIndex = 0;


		//临时保存的桌子中胜利玩家和所有玩家的手牌    依次并列排名
		public List<UserWinList> TempWinnerList = null;
		//临时的手牌数据
		public Dictionary<int, List<int>> TempUserCardsDic = null;
		public Action<TableData> InsuranceCallBack = null;

		/// <summary>
		/// 数据统计
		/// </summary>
		public Dictionary<int, UserGameData> UserGameDatas = null;

		/// <summary>
		/// 保险底池
		/// </summary>
		public List<SimpleInsuranceModelPool> InsurancePool = null;

		/// <summary>
		/// 玩家所在的牌桌的盈亏记录
		/// </summary>
		//public List<UserAndTable> UserAndTables = null;
		/// <summary>
		/// 牌桌表(ID,创建时间,结束时间)
		/// </summary>
		public GameTableData GTableData = null;
		//桌子的逻辑编号
		public int TableLogicID;
		/// <summary>
		/// 当前要下注的位置
		/// </summary>
		public PositionData CurrentBetPos = null;

		public List<int> ForceFoldUserIdList = null;

		/// <summary>
		/// 申请筹码不需要房主确认
		/// </summary>
		public List<int> ApplyChipWithoutConfirmUserIDList;

		//当前牌桌控制买家带入筹码的倍数
		public int MaxMultiple = 1;

		//房间是否暂停
		public bool Pause = false;

		//是否控制玩家买入(如果这个是true的话 设置最大的买入筹码倍数滑动条才会奏效)
		public bool PlayerApplyChipControlSwitch = false;

		/// <summary>
		/// 当前回合购买保险的玩家ID,第二个参数表示是否操作保险完毕
		/// </summary>
		public Dictionary<int, bool> CurrentRoundBuyInsuranceUsersID;

		/// <summary>
		/// 玩家这个保险底池购买的保险金额，最大是底池的总共数量AntNum  注意：不是实际花费的钱
		/// </summary>
		private Dictionary<int, int> TotalInsureUserBuy;

		/// <summary>
		/// 玩家实际得到的赔付
		/// </summary>
		private Dictionary<int, int> TotalInsuranceCompansate;

		/// <summary>
		/// 玩家实际当前底池投入的钱(这个如果最后胜利的话  获得的筹码要减去这部分的钱  这部分是被保险赚走了)
		/// </summary>
		private Dictionary<int, int> TotalUserBuyInsuranceActually;

		/// <summary>
		/// 保险人在当前底池赢/输的钱
		/// </summary>
		public int InsurancerWin = 0;

		/// <summary>
		/// 玩家的下注记录
		/// </summary>
		//public List<UserBetRecord> UserBetRecords = null;

		//public void AddUserBetRecords(UserBetRecord record)
		//{
		//	UserBetRecords.Add(record);
		//}

		/// <summary>
		/// 上一局牌局下注记录
		/// </summary>
		//private List<NewUserBetRecord> formalUserBetRecord = null;
		//private List<int> formalTableCards = null;
		private Dictionary<SimpleUserData, List<int>> formalUserCards = null;
		//private List<SharedUserHandCards> formalUserCards = null;
		//private List<KeyValuePair<int, int>> formalUsersWinChip = null;
		private List<SharedUserInTableHandScore> formalUsersScore = null;

		/// <summary>
		/// 每一手玩家的手牌以及获胜的筹码记录
		/// </summary>
		private Dictionary<int, KeyValuePair<Dictionary<SimpleUserData, List<int>>, List<SharedUserInTableHandScore>>> userHandRecord = null;

		/// <summary>
		/// 当局下注记录
		/// </summary>
		//private List<NewUserBetRecord> currentUserBetRecord = null;
		//private List<int> currentTableCards = null;
		private Dictionary<SimpleUserData, List<int>> currentUserCards = null;
		//private List<SharedUserHandCards> currentUserCards = null;
		//private List<KeyValuePair<int, int>> currentUsersWinChip = null;
		public List<SharedUserInTableHandScore> currentUsersScore = null;

		/// <summary>
		/// 上局牌桌记录
		/// </summary>
		private SharedGameTableCards formalTableCards = null;
		private SharedGameTableCards currentTableCards = null;


		/// <summary>
		/// 上局玩家下注记录
		/// </summary>
		private List<SharedUserBetRecord> formalSharedUserBetRecord = null;
		private List<SharedUserBetRecord> currentSharedUserBetRecord = null;

		/// <summary>
		/// 当前一局牌的所有记录，第一个参数是Hand 第二个是牌桌和玩家下注的记录
		/// </summary>
		private Dictionary<int, KeyValuePair<SharedGameTableCards, List<SharedUserBetRecord>>> gameRecord = null;


		public List<SharedGameTableCards> GameTableCardsList;
		public List<SharedUserAndTable> UserAndTableList;
		public List<SharedUserBetRecord> UserBetRecordList;
		public List<SharedUserHandCards> UserHandCardsList;
		/// <summary>
		/// 每一手牌的玩家盈亏记录
		/// </summary>
		public List<SharedUserInTableHandScore> UserInTableHandScoreList;
		/// <summary>
		/// 保存牌谱
		/// </summary>
		////public List<SharedUserSaveTable> UserSaveTableList;

		/// <summary>
		/// 桌子对象
		/// </summary>
		/// <param name="tableId"></param>
		/// <param name="playerNum"></param>
		/// <param name="callback"></param>
		/// <param name="roomId">房间号</param>
		public TableData(int tableId, int inviteNum, int playerNum, TimerCallback callback, int roomId = 1001)
		{
			_roomId = roomId;
			_tableId = tableId;
			_inviteNum = inviteNum;
			_playerNum = playerNum;

			GameTableCardsList = new List<SharedGameTableCards>();
			UserAndTableList = new List<SharedUserAndTable>();
			UserBetRecordList = new List<SharedUserBetRecord>();
			UserHandCardsList = new List<SharedUserHandCards>();
			UserInTableHandScoreList = new List<SharedUserInTableHandScore>();
			//UserSaveTableList = new List<SharedUserSaveTable>();


			TableInsurer = new Insurer(tableId);
			//InsureChip = new int[9];
			_cardList = new List<int>(PackMaxNum);
			TempBackCardData = new List<int>();
			realTimeRecordList = new Dictionary<int, RealTimeRecord>();
			//InsuranceModelData = new InsuranceModel();
			BackUpCardData = new List<int>();
			_backCardData = new List<int>();
			PlayersData = new List<GameUser>();
			_outCardList = new List<CardData>();
			CurrentPlayingPositionData = new List<PositionData>();
			betRecord = new Dictionary<int, List<KeyValuePair<int, int>>>();
			ApplyChipRecore = new Dictionary<int, int>();
			TempWinnerList = new List<UserWinList>();
			TempUserCardsDic = new Dictionary<int, List<int>>();
			UserGameDatas = new Dictionary<int, UserGameData>();
			InsurancePool = new List<SimpleInsuranceModelPool>();
			//currentUserBetRecord = new List<NewUserBetRecord>();
			//formalUserBetRecord = new List<NewUserBetRecord>();
			formalSharedUserBetRecord = new List<SharedUserBetRecord>();
			currentSharedUserBetRecord = new List<SharedUserBetRecord>();
			gameRecord = new Dictionary<int, KeyValuePair<SharedGameTableCards, List<SharedUserBetRecord>>>();
			formalTableCards = new SharedGameTableCards();
			currentTableCards = new SharedGameTableCards();
			formalUserCards = new Dictionary<SimpleUserData, List<int>>();
			userHandRecord = new Dictionary<int, KeyValuePair<Dictionary<SimpleUserData, List<int>>, List<SharedUserInTableHandScore>>>();
			//formalUsersWinChip = new List<KeyValuePair<int, int>>();
			//currentUsersWinChip = new List<KeyValuePair<int, int>>();
			currentUsersScore = new List<SharedUserInTableHandScore>();
			formalUsersScore = new List<SharedUserInTableHandScore>();
			currentUserCards = new Dictionary<SimpleUserData, List<int>>();
			ForceFoldUserIdList = new List<int>();
			ApplyChipWithoutConfirmUserIDList = new List<int>();
			CurrentRoundBuyInsuranceUsersID = new Dictionary<int, bool>();
			_positions = new PositionData[playerNum];

			this.TotalInsureUserBuy = new Dictionary<int, int>();
			this.TotalInsuranceCompansate = new Dictionary<int, int>();
			this.TotalUserBuyInsuranceActually = new Dictionary<int, int>();

			for (int i = 0; i < playerNum; i++)
			{
				_positions[i] = new PositionData(i);
			}
			_timer = new Timer(callback, this, -1, -1);  //暂时不启动定时器
			TableReadyStart = false;
			//牌桌对象
			GTableData = new GameTableData() { StartTime = DateTime.Now, TableName = TableName };
			//UserAndTables = new List<UserAndTable>();
			//UserBetRecords = new List<UserBetRecord>();

			//this.OperationSecTimeout = ConfigEnvSet.GetInt("GameSetting.OperationSectimeout", 5000);
			this.OperationSecTimeoutOffset = ConfigEnvSet.GetInt("GameSetting.OperationSectimeoutOffset", 500);
			this.MedecineTimeDelay = ConfigEnvSet.GetInt("GameSetting.MedecineTimeDelay", 20000); //延时药水20秒
			this.ChipMoveTimeToTablePool = ConfigEnvSet.GetInt("GameSetting.GameStartCountdown", 3000);
			this.CheckStartTime = ConfigEnvSet.GetInt("GameSetting.CheckStartTime", 2000);
			this.InsuranceOperationTime = ConfigEnvSet.GetInt("GameSetting.InsuranceOperationTime", 20000);
			this.ChipMoveTime = ConfigEnvSet.GetInt("GameSetting.BetDelayTime", 1000);
			this.OperationSecTimeout = 30000; //设置30s操作时间
			this.ForceLeaveFromTableTimeout = ConfigEnvSet.GetInt("GameSetting.ForceLeaveFromTable", 120000);
			//this.ForceLeaveFromTableTimeout = 30000;
			Init();
		}

		/// <summary>
		/// 游戏开始初始化桌面数据
		/// </summary>
		public void Init()
		{
			TimeIsOver = false;
			_currAnteNum = 0;
			_backCardData.Clear();
			BackUpCardData.Clear();
			TempBackCardData.Clear();
			_outCardList.Clear();
			betRecord.Clear();
			ApplyChipRecore.Clear();
			BankerId = 0;
			OutCardPos = 0;
			OutCardUserId = 0;
			IsFlee = false;
			BankerPos = 0;
			InsureOperatePosId = 0;
			IsSettlemented = false;
			IsShow = false;
			HandVersionID = 0;
			//UserBetRecords.Clear();
			//UserAndTables.Clear();
			//currentUserBetRecord.Clear();

			//Array.Clear(this.InsureChip, 0, this.InsureChip.Length);
			StopTimer();
			//重置数据
			//this.TableDataReset();
		}

		#region Timer

		public bool AddForceApplyChipWithoutConfirm(int userId)
		{
			if (ApplyChipWithoutConfirmUserIDList.Contains(userId))
				return false;
			else
				ApplyChipWithoutConfirmUserIDList.Add(userId);
			return true;
		}

		/// <summary>
		/// 房间开始按钮启动倒计时
		/// </summary>
		public void StartTableTimer(int time)
		{
			if (time <= 0)
				return;
			totalSecond = time / 1000;
			this.tableTimer = new System.Timers.Timer(time);
			this.tableTimer.Elapsed += new System.Timers.ElapsedEventHandler(TableTimeOut); //到达时间的时候执行事件；   
			this.tableTimer.AutoReset = false;   //设置是执行一次（false）还是一直执行(true)；   
			this.tableTimer.Enabled = true;     //是否执行System.Timers.Timer.Elapsed事件；
			//记录当前房间的时间
			this.beginTime = DateTime.Now;
		}

		private void TableTimeOut(object source, System.Timers.ElapsedEventArgs e)
		{
			//TODO:倒计时结束设置结束标记这样一局结束不会再开始了，就弹出结账菜单
			Console.WriteLine("*********！！！！！！！！！！！！！！！！！游戏房间时间到！！！！！！！！！！！！！！！！！****************");
			//设置房间时间结束
			this.TimeIsOver = true;
			tableTimer.Enabled = false;
		}

		/// <summary>
		/// 启动定时器
		/// </summary>
		/// <param name="period">时间间隔(单位毫秒)</param>
		public void StartTimer(int period)
		{
			//Console.WriteLine("{0}>>Table:{1} in {2} room timer is started", DateTime.Now.ToString("HH:mm:ss"), _tableId, _roomId);
			if (period <= 0)
				return;
			_timerPeriod = period;
			_timer.Change(period, period);
			_timeNumber = 0;
			IsTimerStarted = true;
		}

		public void ReStartTimer(int period)
		{
			//Console.WriteLine("{0}>>Table:{1} in {2} room timer is restarted", DateTime.Now.ToString("HH:mm:ss"), _tableId, _roomId);
			_timerPeriod = period;
			_timer.Change(-1, -1);
			_timer.Change(period, period);
			_timeNumber = 0;
		}

		public void StopTimer()
		{
			// Console.WriteLine("{0}>>Table:{1} in {2} room timer is stoped", DateTime.Now.ToString("HH:mm:ss"), _tableId, _roomId);
			_timer.Change(-1, -1);
			_timeNumber = 0;
			IsTimerStarted = false;
		}

		/// <summary>
		/// 定时器计数
		/// </summary>
		public void DoTimeNumber()
		{
			Interlocked.Exchange(ref _timeNumber, _timeNumber + _timerPeriod);
		}

		/// <summary>
		/// 操作是否超时
		/// </summary>
		public bool IsOperationTimeout
		{
			get { return _timeNumber > OperationSecTimeout; }
		}

		/// <summary>
		/// 定时器是否开始
		/// </summary>
		public bool IsTimerStarted
		{
			get;
			set;
		}
		#endregion

		#region 数据统计相关
		public void InitUserGameData()
		{
			this.UserGameDatas.Clear();
			foreach (var pos in this.CurrentPlayingPositionData)
			{
				this.UserGameDatas.Add(pos.UserId, new UserGameData());
			}
		}
		//添加总局数统计
		public void AddTotalGameCount()
		{
			foreach (var pos in this.CurrentPlayingPositionData)
			{
				this.AddUserStatisticsData(UserGameDataEnum.TotalPeriodsCount, pos.UserId);
			}
		}

		/// <summary>
		/// 一位胜利玩家统计
		/// </summary>
		public void AddWinnerCount(int userId)
		{
			if (!this.AddUserStatisticsData(UserGameDataEnum.WinPeriodsCount, userId))
				Console.WriteLine("添加胜利玩家数据错误");
		}

		/// <summary>
		/// 判断是否入局
		/// </summary>
		/// <param name="userId"></param>
		/// <returns></returns>
		public bool IsEnterTable(int userId)
		{
			UserGameData data;
			if (this.UserGameDatas.TryGetValue(userId, out data))
			{
				if (data != null)
				{
					if (data.EnterTableCount == 1)
						return true;
				}
			}
			return false;
		}

		/// <summary>
		/// 入局统计
		/// </summary>
		/// <param name="userId"></param>
		public void AddEnterTableCount(int userId)
		{
			if (!this.AddUserStatisticsData(UserGameDataEnum.EnterTableCount, userId))
				Console.WriteLine("添加玩家入局");
		}

		/// <summary>
		/// 翻牌前加注
		/// </summary>
		/// <param name="userId"></param>
		public void AddChipBeforeShowCardCount(int userId)
		{
			if (!this.AddUserStatisticsData(UserGameDataEnum.AddChipBeforeShowCardCount, userId))
				Console.WriteLine("翻牌前加注添加失败");
		}
		/// <summary>
		/// 摊牌
		/// </summary>
		/// <param name="userId"></param>
		public void AddShowCardsCount(int userId)
		{
			if (!this.AddUserStatisticsData(UserGameDataEnum.ShowCardsCount, userId))
				Console.WriteLine("添加摊牌失败");
		}
		/// <summary>
		/// 摊牌胜利
		/// </summary>
		/// <param name="userId"></param>
		public void AddShowCardsAndWinCount(int userId)
		{
			if (!this.AddUserStatisticsData(UserGameDataEnum.WinTimesByShowCardsCount, userId))
				Console.WriteLine("添加摊牌胜利失败");
		}

		/// <summary>
		/// 桌子发了三张牌过后
		/// </summary>
		/// <param name="userId"></param>
		public void AddThreeBETCount(int userId)
		{
			if (!this.AddUserStatisticsData(UserGameDataEnum.ThreeBETCount, userId))
				Console.WriteLine("添加3BET失败");
		}

		/// <summary>
		/// 三张牌发结束时候弃牌(>=第三轮弃牌)
		/// </summary>
		/// <param name="userId"></param>
		public void AddForgiveByThreeBETCount(int userId)
		{
			if (!this.AddUserStatisticsData(UserGameDataEnum.ForgiveByThreeBETCount, userId))
				Console.WriteLine("添加3BET弃牌失败");
		}
		#endregion

		/// <summary>
		/// 是否在初始状态
		/// </summary>
		public bool IsIniting
		{
			get
			{
				return _backCardData.Count == 0;
			}
		}

		/// <summary>
		/// 是否在游戏中
		/// </summary>
		public bool IsStarting
		{
			get { return !IsSettlemented && State == TableState.Playing; }
		}

		/// <summary>
		/// 结算结束
		/// </summary>
		public bool IsSettlemented { get; set; }

		/// <summary>
		/// 是否被释放
		/// </summary>
		public bool IsDisposed { get; private set; }


		/// <summary>
		/// 设置当前回合最大的下注筹码数量的位置
		/// </summary>
		/// <param name="posId"></param>
		public void SetCurrentMaxChipPosId(int posId)
		{
			this.currentRoundMaxChipPosId = posId;
		}

		public void ResetCurrentMaxChipPosId()
		{
			this.currentRoundMaxChipPosId = -1;
		}

		public int CurrentMaxChipPosId
		{
			get { return this.currentRoundMaxChipPosId; }
		}

		/// <summary>
		/// 设置当前回合最大的下注筹码
		/// </summary>
		/// <param name="chip"></param>
		public void SetCurrentMaxChip(int chip)
		{
			this.currentRoundMaxChip = chip;
		}

		public int CurrentMaxChip
		{
			get { return this.currentRoundMaxChip; }
		}

		public void ResetCurrentMaxChip()
		{
			this.currentRoundMaxChip = 0;
		}

		/// <summary>
		/// 获得当前轮流下注的座位
		/// </summary>
		/// <returns></returns>
		public PositionData GetCurrentPosition()
		{
			return this.CurrentBetPos;
		}

		public void TableGameStart()
		{
			HandVersionID++;
			this.State = TableState.Playing;
		}

		/// <summary>
		/// 添加数据统计
		/// </summary>
		/// <param name="type"></param>
		/// <param name="userId"></param>
		public bool AddUserStatisticsData(UserGameDataEnum type, int userId)
		{
			UserGameData data;
			if (this.UserGameDatas.TryGetValue(userId, out data))
			{
				if (data == null)
				{
					Console.WriteLine("统计过程中统计数据不存在");
					return false;
				}
				else
				{
					switch (type)
					{
						case UserGameDataEnum.TotalPeriodsCount:
							{
								if (data.TotalPeriodsCount == 0)
									data.TotalPeriodsCount++;
							}
							break;
						case UserGameDataEnum.WinPeriodsCount:
							{
								if (data.WinPeriodsCount == 0)
									data.WinPeriodsCount++;
							}
							break;
						case UserGameDataEnum.ForgiveByAddChipCount:
							{
								if (data.ForgiveByAddChipCount == 0)
									data.ForgiveByAddChipCount++;
							}
							break;
						case UserGameDataEnum.AddChipBeforeShowCardCount:
							{
								if (data.AddChipCount == 0)
									data.AddChipCount++;
							}
							break;
						case UserGameDataEnum.ThreeBETCount:
							{
								if (data.ThreeBETCount == 0)
									data.ThreeBETCount++;
							}
							break;
						case UserGameDataEnum.ShowCardsCount:
							{
								if (data.ShowCardsCount == 0)
									data.ShowCardsCount++;
							}
							break;
						case UserGameDataEnum.WinTimesByShowCardsCount:
							{
								if (data.WinTimesByShowCardsCount == 0)
									data.WinTimesByShowCardsCount++;
							}
							break;
						case UserGameDataEnum.LookAndShowCardsCount:
							{
								if (data.LookAndShowCardsCount == 0)
									data.LookAndShowCardsCount++;
							}
							break;
						case UserGameDataEnum.EnterTableCount:
							{
								if (data.EnterTableCount == 0)
									data.EnterTableCount++;
							}
							break;
						case UserGameDataEnum.ForgiveByThreeBETCount:
							{
								if (data.ForgiveByThreeBETCount == 0)
									data.ForgiveByThreeBETCount++;
							}
							break;
						default:
							{
								Console.WriteLine("数据出错");
								return false;
							}
					}
				}
			}
			return true;
		}

		/// <summary> 
		/// 玩家实际花的钱(用于结算用)
		/// </summary>
		/// <param name="userId"></param>
		/// <param name="useChip"></param>
		/// <returns></returns>
		public bool AddUserBuyInsuranceActually(int userId, int useChip)
		{
			if (this.TotalUserBuyInsuranceActually.ContainsKey(userId))
			{
				TotalUserBuyInsuranceActually[userId] += useChip;
			}
			else
			{
				this.TotalUserBuyInsuranceActually.Add(userId, useChip);
			}
			return true;
		}

		/// <summary>
		/// 获得玩家当前底池在保险上花掉的筹码实际数量
		/// </summary>
		/// <param name="userId"></param>
		/// <returns></returns>
		public int GetUserTotalUseInInsurance(int userId)
		{
			int num;
			if (this.TotalUserBuyInsuranceActually.TryGetValue(userId, out num))
			{
				return num;
			}
			else
				return 0;
		}

		/// <summary>
		/// 玩家获得的保险赔付
		/// </summary>
		/// <param name="userId"></param>
		/// <returns></returns>
		public int GetUserTotalInsuranceCompansate(int userId)
		{
			int num;
			if (this.TotalInsuranceCompansate.TryGetValue(userId, out num))
			{
				return num;
			}
			else
				return 0;
		}

		//当玩家购买了保险之后，拿到赔付金额的时候要记录到这个已经购买的保险金额的数量里面
		public bool AddInsuranceBuyCount(int userId, int compensateNum)
		{
			int num;
			if (this.TotalInsureUserBuy.TryGetValue(userId, out num))
				this.TotalInsureUserBuy[userId] += compensateNum;
			else
			{
				this.TotalInsureUserBuy.Add(userId, compensateNum);
			}
			return true;
		}

		/// <summary>
		/// 当前底池玩家获得的赔付
		/// </summary>
		/// <param name="userId"></param>
		/// <param name="comPansateNum"></param>
		/// <returns></returns>
		public bool AddInsuranceCompansate(int userId, int comPansateNum)
		{
			int num;
			if (this.TotalInsuranceCompansate.TryGetValue(userId, out num))
				num += comPansateNum;
			else
			{
				this.TotalInsuranceCompansate.Add(userId, comPansateNum);
			}
			return true;
		}

		/// <summary>
		/// 最大可购买的保险金额(如果之前没买过，那就是底池的金额AntNum，  玩家要花的钱是要除以对应的概率)   底池的筹码-当期玩家在这个底池购买的筹码数量
		/// </summary>
		/// <param name="total"></param>
		/// <param name="posId"></param>
		/// <returns></returns>
		public int MaxCanBuyChipNum(int antNum, int userId)
		{
			var total = antNum;
			if (total <= 0)
				return 0;
			int totalCompensate;
			int returnValue;
			if (this.TotalInsureUserBuy.TryGetValue(userId, out totalCompensate))
			{
				returnValue = total - totalCompensate;
				return returnValue <= 0 ? 0 : returnValue;
			}
			else //之前没买过则可以购买
				return total;
		}

		/// <summary>
		/// 添加保险对象
		/// </summary>
		/// <param name="model"></param>
		/// <returns></returns>
		public bool AddInsuranceModel(SimpleInsuranceModelPool model)
		{
			if (this.InsurancePool.Contains(model))
				return false;
			else
				this.InsurancePool.Add(model);
			return true;
		}

		/// <summary>
		/// 添加或者是更新保险对象
		/// </summary>
		/// <param name="model"></param>
		//public void ContainsPoolAndUpdateInfo(SimpleInsuranceModelPool model)
		//{
		//	bool contains = false;
		//	SimpleInsuranceModelPool tempPool = model;
		//	foreach(var pool in this.InsurancePool)
		//	{
		//		if(pool.NumberID == model.NumberID)
		//		{
		//			contains = true;
		//			tempPool = pool;
		//			break;
		//		}
		//	}
		//	if(!contains)
		//	{
		//		this.InsurancePool.Add(model);
		//	}
		//	else
		//	{
		//		//主要就是桌子上的底牌会变，还有maxuserid也会变
		//		tempPool.Common.Clear();
		//		tempPool.Common.AddRange(model.Common);
		//		tempPool.MaxCardsPosId = model.MaxCardsPosId;
		//		tempPool.MaxUserId = model.MaxUserId;
		//	}
		//}

		/// <summary>
		/// 获得上一局的下注记录
		/// </summary>
		/// <returns></returns>
		//public List<NewUserBetRecord> GetFormalUserBetRecord()
		//{
		//	return this.formalUserBetRecord;
		//}

		public List<SharedUserBetRecord> GetFormalUserBetRecord()
		{
			return this.formalSharedUserBetRecord;
		}

		/// <summary>
		/// 获得上一局的牌桌记录
		/// </summary>
		/// <returns></returns>
		public SharedGameTableCards GetFormalTableCards()
		{
			return this.formalTableCards;
		}

		/// <summary>
		/// 根据Hand获得记录牌桌以及下注记录
		/// </summary>
		/// <param name="hand"></param>
		/// <returns></returns>
		public KeyValuePair<SharedGameTableCards, List<SharedUserBetRecord>> GetRecordByHand(int hand)
		{
			KeyValuePair<SharedGameTableCards, List<SharedUserBetRecord>> record;
			this.gameRecord.TryGetValue(hand, out record);
			return record;
		}

		/// <summary>
		/// 返回当前最大的记录HandIndex
		/// </summary>
		/// <returns></returns>
		public int GetCurrentMaxRecordHand()
		{
			int hand = 0;
			foreach(var pair in this.gameRecord)
			{
				if (hand < pair.Value.Key.Hand)
					hand = pair.Value.Key.Hand;
			}
			return hand;
		}

		/// <summary>
		/// 根据hand获得玩家手牌以及获胜的筹码的记录
		/// </summary>
		/// <param name="hand"></param>
		/// <returns></returns>
		public KeyValuePair<Dictionary<SimpleUserData, List<int>>, List<SharedUserInTableHandScore>> GetUserHandScoreByHand(int hand)
		{
			KeyValuePair<Dictionary<SimpleUserData, List<int>>, List<SharedUserInTableHandScore>> record;
			this.userHandRecord.TryGetValue(hand, out record);
			return record;
		}

		//public bool AddCurrentUsersWinChip(KeyValuePair<int, int> winRecord)
		//{
		//	if (this.currentUsersWinChip.Contains(winRecord))
		//		return false;
		//	this.currentUsersWinChip.Add(winRecord);
		//	return true;
		//}


		public bool AddCurrentUserScore(SharedUserInTableHandScore score)
		{
			if (this.currentUsersScore.Contains(score))
				return false;
			else
			{
				this.currentUsersScore.Add(score);
				return true;
			}
		}

		public DateTime BeginTime()
		{
			return this.beginTime;
		}

		/// <summary>
		/// 获得房间的剩余时间(秒)
		/// </summary>
		/// <returns></returns>
		public int GetLeftTime()
		{
			if (beginTime == null)
				return 0;
			TimeSpan sp = DateTime.Now - beginTime;
			var leftSecond = totalSecond - sp.Seconds;
			return leftSecond > 0 ? leftSecond : 0;
		}

		/// <summary>
		/// 获得上一局的玩家手牌记录
		/// </summary>
		/// <returns></returns>
		public Dictionary<SimpleUserData, List<int>> GetFormalUserCards()
		{
			return this.formalUserCards;
		}

		/// <summary>
		/// 获得上一局玩家的获胜的筹码
		/// </summary>
		/// <returns></returns>
		//public List<KeyValuePair<int, int>> GetFormalUsersWinChipNum()
		//{
		//	return this.formalUsersWinChip;
		//}

		/// <summary>
		/// 获得上一局玩家获胜的筹码
		/// </summary>
		/// <returns></returns>
		public List<SharedUserInTableHandScore> GetFormalUsersScore()
		{
			return this.formalUsersScore;
		}

		/// <summary>
		/// 当手牌局数据保存
		/// </summary>
		/// <returns></returns>
		public bool SyncCurrentHandRecord()
		{
			//this.formalUserBetRecord.Clear();
			//this.formalUserBetRecord.AddRange(this.currentUserBetRecord);
			//this.currentUserBetRecord.Clear();

			this.formalSharedUserBetRecord.Clear();
			this.formalSharedUserBetRecord.AddRange(this.currentSharedUserBetRecord);
			this.currentSharedUserBetRecord.Clear();
			this.UserBetRecordList.AddRange(this.formalSharedUserBetRecord);  //添加所有的下注记录


			//玩家手牌记录
			this.formalUserCards.Clear();
			foreach (var pair in this.currentUserCards)
			{
				var simpleUser = new SimpleUserData();
				simpleUser.UserId = pair.Key.UserId;
				simpleUser.HeadIcon = pair.Key.HeadIcon;
				simpleUser.NickName = pair.Key.NickName;
				var cards = new List<int>();
				cards.AddRange(pair.Value);
				this.formalUserCards.Add(simpleUser, cards);
				this.UserHandCardsList.Add(new SharedUserHandCards() { TableID = TableLogicID, UserID = simpleUser.UserId, Hand = HandVersionID, Card0 = cards[0], Card1 = cards[1] });
			}
			this.currentUserCards.Clear();


			var cardArray = new int[] { 0, 0, 0, 0, 0 };
			for (int i = 0; i < TempBackCardData.Count; i++)
			{
				cardArray[i] = TempBackCardData[i];
			}
			this.currentTableCards.Card0 = cardArray[0];
			this.currentTableCards.Card1 = cardArray[1];
			this.currentTableCards.Card2 = cardArray[2];
			this.currentTableCards.Card3 = cardArray[3];
			this.currentTableCards.Card4 = cardArray[4];
			this.currentTableCards.TableID = TableLogicID;
			this.currentTableCards.Hand = HandVersionID;

			//牌桌上的牌记录
			this.formalTableCards.TableID = this.currentTableCards.TableID;
			this.formalTableCards.Hand = this.currentTableCards.Hand;
			this.formalTableCards.Card0 = this.currentTableCards.Card0;
			this.formalTableCards.Card1 = this.currentTableCards.Card1;
			this.formalTableCards.Card2 = this.currentTableCards.Card2;
			this.formalTableCards.Card3 = this.currentTableCards.Card3;
			this.formalTableCards.Card4 = this.currentTableCards.Card4;
			this.formalTableCards.TableID = this.currentTableCards.TableID;
			this.formalTableCards.Hand = this.currentTableCards.Hand;

			this.GameTableCardsList.Add(new SharedGameTableCards() { TableID = formalTableCards.TableID, Hand = formalTableCards.Hand, Card0 = formalTableCards.Card0, Card1 = formalTableCards.Card1, Card2 = formalTableCards.Card2, Card3 = formalTableCards.Card3, Card4 = formalTableCards.Card4 });

			//将上一局结果保存到记录中
			gameRecord.Add(HandVersionID, new KeyValuePair<SharedGameTableCards, List<SharedUserBetRecord>>(new SharedGameTableCards(this.formalTableCards), new List<SharedUserBetRecord>(this.formalSharedUserBetRecord)));
			
			//玩家成绩
			this.formalUsersScore.Clear();
			this.formalUsersScore.AddRange(this.currentUsersScore);
			this.currentUsersScore.Clear();

			var d = new Dictionary<SimpleUserData, List<int>>(this.formalUserCards);
			var l = new List<SharedUserInTableHandScore>(this.formalUsersScore);
			userHandRecord.Add(HandVersionID, new KeyValuePair<Dictionary<SimpleUserData, List<int>>, List<SharedUserInTableHandScore>>(d, l));

			return true;
		}


		//老的添加玩家下注记录
		//public bool AddUserBetRecordInCurrent(NewUserBetRecord record)
		//{
		//	if (this.currentUserBetRecord.Contains(record))
		//	{
		//		Console.WriteLine("已经包含了该记录");
		//		return false;
		//	}
		//	else
		//	{
		//		this.currentUserBetRecord.Add(record);
		//	}
		//	return true;
		//}

		/// <summary>
		/// 添加玩家下注记录
		/// </summary>
		/// <param name="record"></param>
		/// <returns></returns>
		public bool AddUserBetRecordInCurrent(SharedUserBetRecord record)
		{
			if (this.currentSharedUserBetRecord.Contains(record))
			{
				return false;
			}
			else
			{
				this.currentSharedUserBetRecord.Add(record);
			}
			return true;
		}



		/// <summary>
		/// 添加当前一个玩家的手牌到当前牌局玩家手牌记录
		/// </summary>
		/// <param name="userCards"></param>
		/// <returns></returns>
		public bool AddCurrentUserCards(KeyValuePair<SimpleUserData, List<int>> userCards)
		{
			if (this.currentUserCards.ContainsKey(userCards.Key))
			{
				return false;
			}
			this.currentUserCards.Add(userCards.Key, userCards.Value);
			return true;
		}

		/// <summary>
		/// 添加玩家下注的日志
		/// </summary>
		/// <param name="record"></param>
		/// <returns></returns>
		public bool AddUserBetRecordLog(LogUserBetRecord record)
		{
			if (record == null)
				return false;
			var sender = DataSyncManager.GetDataSender();
			return sender.Send(new[] { record });
		}

		/// <summary>
		/// 一手结束，桌子相关的数据重置
		/// </summary>
		public void TableDataReset()
		{
			this._backCardData.Clear();
			this.betRecord.Clear();
			this.ApplyChipRecore.Clear();
			this.BankerPos = 0;
			this.BackUpCardData.Clear();
			this.TempBackCardData.Clear();
			//this.InsuranceModelData.Clear();
			if (this.tempTableChipPool != null)
				this.tempTableChipPool.Clear();
			if (this.tempInsuranceRecord != null)
				this.tempInsuranceRecord.Clear();
			this._currAnteNum = 0;
			//当前正在玩的座位
			this.CurrentPlayingPositionData.Clear();
			this.CurrentInsurancePos = null;
			this.currentPosIndex = 0;
			this.currentRoundMaxChipPosId = -1;
			this.Round = 0;
			this.FirstRoundAllInInInsuranceTable = false;
			this.FirstRoundAllInPopCardTimes = 0;
			this.FormalNormalOperatePosID = 0;
			this.AllInState = false;
			this.FormalOperatePosId = 0;
			this.IsHavaSendCards = false;
			this.InsureOperatePosId = 0;

			this.TempWinnerList.Clear();
			this.TempUserCardsDic.Clear();
			this.UserGameDatas.Clear();

			this.TotalInsureUserBuy.Clear();
			this.TotalInsuranceCompansate.Clear();
			this.TotalUserBuyInsuranceActually.Clear();

			foreach (var pool in this.InsurancePool)
			{
				pool.Clear();
			}
			this.InsurancePool.Clear();

			this.InsuranceCallBack = null;
			Array.Clear(this.MaxScore, 0, MaxScore.Length);
			Array.Clear(this.TotalScore, 0, TotalScore.Length);
			Array.Clear(this.TableScore, 0, TableScore.Length);
			//Array.Clear(this.InsureChip, 0, this.InsureChip.Length);
			//每个位置数据的重置
			foreach (var pos in Positions)
			{
				pos.DataReset();
			}
		}

		/// <summary>
		/// 添加底池数量
		/// </summary>
		/// <param name="pos"></param>
		/// <param name="chipNum"></param>
		/// <returns></returns>
		public bool AddTempTableChipPoolData(int posid, int chipNum)
		{
			if (this.tempTableChipPool == null)
				this.tempTableChipPool = new Dictionary<int, int>();
			int num;
			if (!this.tempTableChipPool.TryGetValue(posid, out num))
			{
				this.tempTableChipPool.Add(posid, chipNum);
				return true;
			}
			else
			{
				Console.WriteLine(string.Format("已经存在该玩家:{0}的数据", posid));
				return false;
			}
		}

		/// <summary>
		/// 清空几个零时的底池筹码
		/// </summary>
		public void ClearTempTableChip()
		{
			this.tempTableChipPool.Clear();
		}

		/// <summary>
		/// 移除临时底池的数量
		/// </summary>
		/// <param name="posId"></param>
		/// <returns></returns>
		public bool RemoveTempTableChip(int posId)
		{
			return this.tempTableChipPool.Remove(posId);
		}

		/// <summary>
		/// 添加玩家购买保险的记录
		/// </summary>
		/// <param name="posid">位置ID</param>
		/// <param name="insuranceChip">购买的保险金额</param>
		/// <param name="payInsuranceNum">实际支付的保险金额</param>
		public void AddInsuranceRecordData(int posid, int insuranceChip, int payInsuranceNum)
		{
			if (this.tempInsuranceRecord == null)
				this.tempInsuranceRecord = new Dictionary<int, List<KeyValuePair<int, int>>>();
			List<KeyValuePair<int, int>> pairValueList;
			if (!this.tempInsuranceRecord.TryGetValue(posid, out pairValueList))
			{
				var list = new List<KeyValuePair<int, int>>();
				list.Add(new KeyValuePair<int, int>(insuranceChip, payInsuranceNum));
				this.tempInsuranceRecord.Add(posid, list);
			}
			else
			{
				pairValueList.Add(new KeyValuePair<int, int>(insuranceChip, payInsuranceNum));
			}
		}

		/// <summary>
		/// 从正在玩的列表里面移除掉弃牌的玩家
		/// </summary>
		/// <param name="pos"></param>
		/// <returns></returns>
		public bool RemoveFoldPosition(PositionData pos)
		{
			if (this.CurrentPlayingPositionData.Contains(pos))
				return this.CurrentPlayingPositionData.Remove(pos);
			else
				return false;
		}

		/// <summary>
		/// 获得下一个正在玩的座位
		/// </summary>
		/// <returns></returns>
		public PositionData GetNextPosition()
		{
			//要排除已经AllIn或者弃牌的玩家
			var positions = this.CurrentPlayingPositionData;

			//重新调整一下currentPosIndex，一个玩家看牌接着还是他下注导致的currentPosIndex错乱的bug
			for (int i = 0; i < positions.Count; i++)
			{
				if (positions[i].Id == this.FormalOperatePosId)
				{
					this.currentPosIndex = i;
					break;
				}
			}
			int tempPosIndex = this.currentPosIndex;
			if (this.currentPosIndex + 1 >= positions.Count)
			{
				this.currentPosIndex = 0;
			}
			else
			{
				tempPosIndex = ++this.currentPosIndex;
			}
			var pos = positions[this.currentPosIndex];
			//如果当前这个座位就是回合内下注最大的座位就返回为空
			if (pos.Id == this.currentRoundMaxChipPosId)
			{
				this.currentPosIndex = tempPosIndex;
				return null;
			}
			if (pos.PlayState != PositionPlayState.Fold && pos.PlayState != PositionPlayState.AllIn && pos.PlayState != PositionPlayState.None)
			{
				var nextPosition = positions[this.currentPosIndex];
				Console.WriteLine("获得下一个位置 并且设置可以下注:" + nextPosition.Id);
				nextPosition.BetState = true;
				return nextPosition;
			}
			//如果是弃牌或者是AllIn还是要标记一下他已经下注操作过了，以便索引继续寻找下一位
			this.FormalOperatePosId = pos.Id;
			return GetNextPosition();
		}

		/// <summary>
		/// 添加加入牌局的玩家(必须是已经加入的状态posType是Play才算是正在玩的玩家，并且是在游戏开始的时候才统一加入)
		/// </summary>
		/// <param name="positiondata"></param>
		public void InsertPlayingPosition(PositionData positiondata)
		{
			if (this.CurrentPlayingPositionData.Contains(positiondata))
				return;
			positiondata.PlayState = PositionPlayState.Add;
			this.CurrentPlayingPositionData.Add(positiondata);
		}

		/// <summary>
		/// 判断除了我,除了弃牌的玩家其他所有的玩家是否全都AllIn    (有且仅有一个人还有筹码)
		/// </summary>
		/// <returns></returns>
		public bool PlayersAreAllInExceptFold()
		{
			int count = 0;
			foreach (var position in this.CurrentPlayingPositionData)
			{
				if (position.PlayState != PositionPlayState.Fold && position.Chip > 0)  //不是弃牌状态，并且还有筹码
					count++;
				if (count > 1)
					return false;
			}
			return true;
		}

		/// <summary>
		/// 添加筹码记录
		/// </summary>
		/// <returns></returns>
		public bool AddRealTimeRecord(GameUser user)
		{
			var userId = user.GetUserId();
			if (this.realTimeRecordList.ContainsKey(userId))
			{
				return false;
			}
			var record = new RealTimeRecord()
			{
				BuyChip = 0,
				SUser = new SimpleUserData() { HeadIcon = user.HeadIcon, NickName = user.GetNickName(), UserId = userId },
				WinChip = 0,
				LeftChip = 0,
			};
			this.realTimeRecordList.Add(userId, record);
			return true;
		}

		public Dictionary<int, RealTimeRecord> GetRealTimeRecordList()
		{
			return this.realTimeRecordList;
		}

		/// <summary>
		/// 返回实时战绩
		/// </summary>
		/// <returns></returns>
		public RealTimeRecord GetRealTimeRecord(int userId)
		{
			RealTimeRecord record = null;
			if (this.realTimeRecordList.TryGetValue(userId, out record))
			{
				return record;
			}
			return null;
		}

		public bool ModifyRecord(int userId, int leftChip)
		{
			RealTimeRecord record = null;
			if (this.realTimeRecordList.TryGetValue(userId, out record))
			{
				record.LeftChip = leftChip;
				return true;
			}
			return false;
		}

		/// <summary>
		/// 修改实时战绩
		/// </summary>
		/// <param name="userId"></param>
		/// <param name="buyChipNum">又继续购买的筹码数量，累加变量</param>
		/// <param name="leftChip">剩余的筹码数量，直接替换数值</param>
		public bool AddRealTimeRecord(int userId, int addBuyChipNum, int addLeftChip = 0)
		{
			RealTimeRecord record = null;
			if (this.realTimeRecordList.TryGetValue(userId, out record))
			{
				record.BuyChip += addBuyChipNum;
				record.LeftChip += addLeftChip;
				return true;
			}
			return false;
		}

		/// <summary>
		/// 获得最后一个没有弃牌的玩家
		/// </summary>
		/// <returns></returns>
		public PositionData GetWinner()
		{
			foreach (var position in this.CurrentPlayingPositionData)
			{
				if (position.PlayState != PositionPlayState.Fold)
					return position;
			}
			return null;
		}

		/// <summary>
		/// 就剩唯一的一个玩家没有弃牌
		/// </summary>
		/// <param name="posId"></param>
		/// <returns></returns>
		public bool OtherPlayersAreAllFoldExceptOne()
		{
			int posId = 0;
			foreach (var position in this.CurrentPlayingPositionData)
			{
				if (position.PlayState != PositionPlayState.Fold)
				{
					if (posId == 0)
						posId = position.Id;
					else
						return false;
				}
			}
			return true;
		}

		/// <summary>
		/// 获得庄家
		/// </summary>
		/// <returns></returns>
		public PositionData GetBanker()
		{
			var positions = this.CurrentPlayingPositionData;
			if (this.bankerIndex >= positions.Count - 1)
				this.bankerIndex = 0;
			else
				this.bankerIndex++;
			var pos = positions[this.bankerIndex];
			this.currentPosIndex = this.bankerIndex;
			//设置当前玩家
			this.currentBankerPos = pos;
			return pos;
		}

		/// <summary>
		/// 获得当前准备就绪的座位
		/// </summary>
		/// <returns></returns>
		public List<PositionData> GetCurrentGetReadyPosition()
		{
			var positions = new List<PositionData>();
			foreach (var pos in this.Positions)
			{
				var isReady = pos.Ready();
				var chip = pos.Chip;
				if (!isReady || chip <= 0)
					continue;
				positions.Add(pos);
			}
			return positions;
		}

		/// <summary>
		/// 按照ID从小到大排序
		/// </summary>
		/// <param name="list"></param>
		public void SortPositionData(ref List<PositionData> datas)
		{
			datas.Sort((i, j) => i.Id > j.Id ? 1 : -1);
		}

		/// <summary>
		/// 选择某个座位坐下
		/// </summary>
		/// <param name="posId"></param>
		/// <param name="user"></param>
		/// <returns></returns>
		public bool SitDown(PositionData posData, GameUser user, PositionPlayState playState = PositionPlayState.None)
		{
			if (posData == null)
				return false;
			posData.Init(_tableId, user, playState);
			return true;
		}

		/// <summary>
		/// 站起
		/// </summary>
		/// <param name="posId">1-9  因为玩家默认的PositionId就是0</param>
		/// <param name="user"></param>
		/// <returns></returns>
		public bool StandUp(PositionData posData, GameUser user)
		{
			if (posData == null)
				return false;
			//将剩余筹码添加到实时战绩中，可以用于下一回合再坐下
			if (AddRealTimeRecord(user.GetUserId(), 0, posData.Chip))
				posData.Chip = 0;
			else
			{
				Console.WriteLine(string.Format("桌子:{0} 位置:{1} 站起  之前没有保存他的实时战绩记录", _tableId, posData.Id));
				return false;
			}
			//移除面申请带入
			ApplyChipWithoutConfirmUserIDList.Remove(user.UserId);
			user.Property.SetTablePositionId(_tableId, 0);
			posData.UserId = 0;
			posData.PlayState = PositionPlayState.None;
			//重置
			posData.PosDataClear();
			return true;
		}

		/// <summary>
		/// 一个回合结束重置数据
		/// </summary>
		public void RoundReset()
		{
			this.ResetCurrentMaxChip();
			this.ResetCurrentMaxChipPosId();
		}

		/// <summary>
		/// 设置下注记录
		/// </summary>
		/// <param name="round"></param>
		/// <param name="posId"></param>
		/// <param name="chip"></param>
		public void SetBetRecord(int round, int posId, int chip)
		{
			List<KeyValuePair<int, int>> betRoundRecord;
			if (!betRecord.TryGetValue(round, out betRoundRecord))
			{
				betRoundRecord = new List<KeyValuePair<int, int>>();
				var pair = new KeyValuePair<int, int>(posId, chip);
				betRoundRecord.Add(pair);
				this.betRecord.Add(round, betRoundRecord);
			}
			else
			{
				var pair = new KeyValuePair<int, int>(posId, chip);
				betRoundRecord.Add(pair);
			}
			try
			{
				this.TotalScore[posId - 1] += chip;  //TotalScore所有玩家的筹码
			}
			catch (Exception ex)
			{
				Console.WriteLine("记录下注记录位置有问题" + posId);
				Console.WriteLine(ex.ToString());
			}
		}

		public void ClearTable()
		{
			foreach (var user in this.PlayersData)
			{
				user.Property.Clear(this._tableId);
			}
			foreach (var pos in this.Positions)
			{
				pos.Chip = 0;
			}
			TableDataReset();

			//this.currentUserBetRecord.Clear();
			//this.formalUserBetRecord.Clear();
			this.formalTableCards = null;
			this.gameRecord.Clear();
			this.userHandRecord.Clear();
			this.currentTableCards = null;
			this.formalUserCards.Clear();
			this.currentUserCards.Clear();
			this.ForceFoldUserIdList.Clear();
			this.ApplyChipWithoutConfirmUserIDList.Clear();
			//this.currentUsersWinChip.Clear();
			//this.formalUsersWinChip.Clear();
			this.currentUsersScore.Clear();
			this.formalUsersScore.Clear();
			this.InsurancePool.Clear();
			this.TotalInsureUserBuy.Clear();
			this.TotalInsuranceCompansate.Clear();
			this.TotalUserBuyInsuranceActually.Clear();

			//删除掉这个桌子相关的邀请信息
			//this.DeleteAllInviteInfo(this.TableId);

			GameTableCardsList.Clear();
			UserAndTableList.Clear();
			UserBetRecordList.Clear();
			UserHandCardsList.Clear();
			UserInTableHandScoreList.Clear();
			//UserSaveTableList.Clear();

			this.Dispose(true);
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				//释放 托管资源 
				_timer.Dispose();
				_timer = null;
				_backCardData = null;
				_outCardList = null;
				_cardList = null;
				betRecord = null;
				TotalScore = null;
				CurrentInsurancePos = null;
				CurrentPlayingPositionData = null;
				IsDisposed = true;
				//InsureChip = null;
				TableInsurer = null;
				TableMaster = null;
				realTimeRecordList.Clear();
				realTimeRecordList = null;
				//currentUserBetRecord = null;
				//formalUserBetRecord = null;
				_playerData.Clear();
				_playerData = null;
				//UserBetRecords = null;
				//UserAndTables = null;
				GTableData = null;
				CurrentBetPos = null;
				ForceFoldUserIdList = null;
				ApplyChipWithoutConfirmUserIDList = null;
				this.TotalInsureUserBuy = null;
				this.TotalInsuranceCompansate = null;
				this.TotalUserBuyInsuranceActually = null;

				gameRecord = null;
				userHandRecord = null;
				GameTableCardsList = null;
				UserAndTableList = null;
				UserBetRecordList = null;
				UserHandCardsList = null;
				UserInTableHandScoreList = null;
				//UserSaveTableList = null;
			}
			base.Dispose(disposing);
		}
	}
}
